package com.och.mrcp.core.sip.parser;

import com.och.mrcp.core.sip.model.SipMessage;
import com.och.mrcp.core.sip.model.SipRequest;
import com.och.mrcp.core.sip.model.SipResponse;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.StandardCharsets;

@Slf4j
public class SipMessageParser {
    
    public static SipMessage parse(String rawMessage) {
        try {
            String[] lines = rawMessage.split("\r\n");
            if (lines.length < 2) {
                throw new IllegalArgumentException("Invalid SIP message format");
            }
            
            String startLine = lines[0];
            if (startLine.startsWith("SIP/")) {
                return parseResponse(rawMessage, lines);
            } else {
                return parseRequest(rawMessage, lines);
            }
        } catch (Exception e) {
            log.error("Failed to parse SIP message: {}", e.getMessage(), e);
            throw new RuntimeException("SIP message parsing failed", e);
        }
    }
    
    private static SipRequest parseRequest(String rawMessage, String[] lines) {
        SipRequest request = new SipRequest();
        request.setRawMessage(rawMessage);
        
        // Parse start line
        String[] startLineParts = lines[0].split(" ");
        if (startLineParts.length >= 3) {
            request.setMethod(startLineParts[0]);
            request.setRequestUri(startLineParts[1]);
            request.setSipVersion(startLineParts[2]);
            request.setStartLine();
        }
        
        // Parse headers
        parseHeaders(request, lines);
        
        // Parse body
        parseBody(request, rawMessage);
        
        return request;
    }
    
    private static SipResponse parseResponse(String rawMessage, String[] lines) {
        SipResponse response = new SipResponse();
        response.setRawMessage(rawMessage);
        
        // Parse start line
        String[] startLineParts = lines[0].split(" ");
        if (startLineParts.length >= 3) {
            response.setSipVersion(startLineParts[0]);
            response.setStatusCode(Integer.parseInt(startLineParts[1]));
            response.setReasonPhrase(startLineParts[2]);
            response.setStartLine();
        }
        
        // Parse headers
        parseHeaders(response, lines);
        
        // Parse body
        parseBody(response, rawMessage);
        
        return response;
    }
    
    private static void parseHeaders(SipMessage message, String[] lines) {
        int i = 1;
        while (i < lines.length && !lines[i].trim().isEmpty()) {
            String line = lines[i];
            int colonIndex = line.indexOf(':');
            if (colonIndex > 0) {
                String name = line.substring(0, colonIndex).trim();
                String value = line.substring(colonIndex + 1).trim();
                
                // 处理多行头部值
                while (i + 1 < lines.length && 
                       (lines[i + 1].startsWith(" ") || lines[i + 1].startsWith("\t"))) {
                    value += " " + lines[i + 1].trim();
                    i++;
                }
                
                message.addHeader(name, value);
                
                // 设置常用头部字段
                switch (name.toLowerCase()) {
                    case "call-id":
                        message.setCallId(value);
                        break;
                    case "cseq":
                        message.setCseq(value);
                        break;
                    case "from":
                        message.setFrom(value);
                        break;
                    case "to":
                        message.setTo(value);
                        break;
                    case "via":
                        message.setVia(value);
                        break;
                    case "contact":
                        message.setContact(value);
                        break;
                    case "content-type":
                        message.setContentType(value);
                        break;
                    case "content-length":
                        try {
                            message.setContentLength(Integer.parseInt(value));
                        } catch (NumberFormatException e) {
                            log.warn("Invalid Content-Length: {}", value);
                        }
                        break;
                }
            }
            i++;
        }
    }
    
    private static void parseBody(SipMessage message, String rawMessage) {
        try {
            int sep = rawMessage.indexOf("\r\n\r\n");
            if (sep < 0) {
                return;
            }
            String bodyStr = rawMessage.substring(sep + 4);
            if (bodyStr.isEmpty()) {
                return;
            }
            message.setBody(bodyStr);
            // 验证Content-Length（按字节）
            int byteLen = bodyStr.getBytes(StandardCharsets.UTF_8).length;
            if (message.getContentLength() > 0 && byteLen != message.getContentLength()) {
                log.debug("Body byte length ({}) doesn't match Content-Length ({})", byteLen, message.getContentLength());
            }
        } catch (Exception e) {
            log.error("Failed to parse SIP body: {}", e.getMessage(), e);
        }
    }
}
